import EnvConfig from "../config/EnvConfig"
import Point from "../entity/Point"



export default class L_Math{

private static  M_PI= 3.141
public static  BJ_RADTODEG= 57.306  //180.0/L_Math.M_PI
public static  BJ_DEGTORAD=0.01745 //L_Math.M_PI/180.0


 //4位字符串id转整型
 static ID2I(str: string):number {
    let bArr: any[] = this.stringToBytes(str)
    let i = bArr[0]
    i = i * 256 + bArr[1]
    i = i * 256 + bArr[2]
    i = i * 256 + bArr[3]
    return i
}

//整型id转4位字符串
static I2ID(id:number):string{
    return this.byteToString(id/0x1000000)+this.byteToString(id/0x10000%0x100)+this.byteToString(id/0x100%0x100)+this.byteToString(id%0x100)
 }

 //id转换用到的辅助转换
 private static stringToBytes(str: string) {

    let bytes = [];
    let len, c;
    len = str.length;
    for (let i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if (c >= 0x010000 && c <= 0x10FFFF) {
            bytes.push(((c >>> 18) & 0x07) | 0xF0);
            bytes.push(((c >>> 12) & 0x3F) | 0x80);
            bytes.push(((c >>> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000800 && c <= 0x00FFFF) {
            bytes.push(((c >>> 12) & 0x0F) | 0xE0);
            bytes.push(((c >>> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000080 && c <= 0x0007FF) {
            bytes.push(((c >>> 6) & 0x1F) | 0xC0);
            bytes.push((c & 0x3F) | 0x80);
        } else {
            bytes.push(c & 0xFF);
        }
    }
    return bytes;
}
   //id转换用到的辅助转换
private static byteToString(fv:number): string {
    return String.fromCharCode(Math.floor(fv))
}


static getBINArr(v:number):number[]{ 
    let r:number[]=[]
    let index=0
    if( v>0 ){
        while(v>0) {
            let tmp=v%2
            //r=ArrayX.push(r,tmp)
            v=Math.floor(v/2)
            r[index]=tmp
            index++
            //table.insert(r,tmp)
        }
    }  
    return r
}




/**两点坐标形成的角度 */
static getAngle(startX:number,startY:number,targetX:number,targetY:number):number{
 return L_Math.BJ_RADTODEG*math.atan((targetY-startY),(targetX-startX))
}

/**获取点(x,y)作为起始 角度为angel 距离dis的点 */
static getAgDisLoc(x:number,y:number,angel:number,dis:number):Point{
    let rx=x + dis * math.cos(angel * L_Math.BJ_DEGTORAD)
    let ry=y + dis * math.sin(angel * L_Math.BJ_DEGTORAD)
    return {x:rx,y:ry}
}    




/**   点是否在矩形内
  * @param px  点x坐标
  * @param py  点y坐标
  * @param rcx  矩形区域开始边的中心x坐标
  * @param rcy  矩形区域开始边的中心y坐标
  * @param tx  目标点x坐标   (目标点和矩形中心点  决定矩形延申方向)
  * @param ty  目标点y坐标
  * @param width  矩形宽度
  * @param length  矩形长度
*/
static xyInRect(px:number,py:number,rcx:number,rcy:number,tx:number,ty:number,width:number,length:number){
  //推导斜率相等的两条线公式
  let angle= this.getAngle(rcx,rcy,ty,tx)

  //矩形左下角开始逆时针4个点
  let p1=this.getAgDisLoc(rcx,rcy,angle+90,width/2)
  let p2=this.getAgDisLoc(rcx,rcy,angle-90,width/2)
  let p3=this.getAgDisLoc(p2.x,p2.y,angle,length)
  let p4=this.getAgDisLoc(p1.x,p1.y,angle,length)
  let p={x:px,y:py}

  // 指导思想点是否在边的一侧 -> 点在两条边之间
  // (AB X AE ) * (CDX CE)  >= 0 就说明E在AD和BC中间夹着，同理(DA X DE ) * (BC X BE) >= 0计算另两边AB,CD就可以了
  // (AB X AE ) * (CD X CE)  >= 0 && (DA X DE ) * (BC X BE) >= 0 
   return (this.GetCross(p1, p2, p) * this.GetCross(p3, p4, p) >= 0 ) && (this.GetCross(p2, p3, p) * this.GetCross(p4, p1, p) >= 0)
}

// 计算 |p1 p2| X |p1 p|
private static GetCross(p1:Point, p2:Point, p:Point) {
    return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
}


// >>>>>>>>>>>未使用的的点在矩形思路  （点到边的距离）<<<<<<<<<<<<<<<<<

  //直线一般表达式  Ax + By + C = 0
  //直线斜率表达式  y = kx + b
  //斜率转换一般表达式 -kx+y-b=0
  // A=-kx  , B=1 ,C=-b(b为y轴截距)

  // 点到直线距离公式 d = |Ax + By + C| / sqrt(A^2 + B^2)

  // 平行线的距离公式  d= |C1-C2|/sqrt(A^2 + B^2)
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  

// let vx=getBINArr(55);
// console.log(LT_FUNC.getObjJSONStr(vx))


/**
 * 简单判断两个单位距离是否在目标距离之内
 * @param aunit 
 * @param bunit 
 * @param targetDis 
 * @returns 
 */
static unitInDisBySimpleSts(aunit:unit,bunit:unit,targetDis:number):boolean{
    if(!EnvConfig.devMod) {
        return L_Math.absVal(L_Math.absVal( GetUnitX(aunit))-L_Math.absVal( GetUnitX(bunit)))<=targetDis 
               && L_Math.absVal(L_Math.absVal( GetUnitY(aunit))-L_Math.absVal( GetUnitY(bunit)))<=targetDis
    } 
    return true
}


private static absVal (v:number):number{
    if (v >= 0) {
        return v
    }else{
        return -v
    }
}
    
}